home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
language
/
embedded
/
mcu
/
float09.arc
/
INS.SA
< prev
next >
Wrap
Text File
|
1987-03-04
|
13KB
|
560 lines
NAM INS
TTL DECIMAL INPUT ROUTINE
*
* DEFINE EXTERNAL REFERENCES
*
XDEF DECBIN
*
XREF PWRTEN,ROUND,CHKUNF,CHKOVF,RTNAN,OVFLNT,UNFLNT
XREF LNORM,FMUL,FDIV,FPMOVE,CLRES,IOPSUB,IOPSET
XREF RTZERO,DENORM
*
*
* REVISION HISTORY:
* DATE PROGRAMMER REASON
*
* 23.MAY.80 G.WALKER & ORIGINAL
* 17.JUN.80 G. STEVENS FIX DECBIN
* 05.AUG.80 G. STEVENS FIX DECBIN( S FOR U TYPO )
* 28.AUG.80 J. BONEY CLEAR INEXACT BEFORE LAST ROUND
* 28.AUG.80 G. STEVENS CHECK FOR ZERO FRACTION STRING
* 24.OCT.80 G. STEVENS FIX UP BCD MINUS SIGN PROBLEM
* 15.DEC.80 G. STEVENS SET STIKY PROPERLY FOR FINAL ROUND
*
*
PAG
*
* LOCAL EQUATES
*
DMINUS EQU $0F BCD STRING MINUS SIGN
DPLUS EQU 00 BCD STRING PLUS SIGN
*
************************************************************
*
* PROCEDURE STRBIN
*
* STRBIN CONVERTS A SIGNED UNPACKED BCD STRING
* REPRESENTING A FLOATING PT. SIGNIFICAND AND CONVERTS
* IT TO A BINARY FLOATING PT. NO. IN INTERNAL FORMAT.
*
* ON ENTRY: X - POINTS TO THE INTERNAL STACK LOCATION
* OF THE RESULTING FLOATING VALUE.
*
* Y - POINTS TO THE START OF THE BCD STRING
*
*
*
* REGISTERS EQUATES
*
ALL REG CC,A,B,X,Y,U
*
STRBIN EQU *
*
* CONVERT FRACTION STRING TO A BINARY INTEGER
*
LEAX FRACT,X
*
LBSR STRINT
*
LEAX -FRACT,X
*
* SET THE SIGN OF THE RESULT TO THE SIGN OF THE
* BCD STRING.
*
*
LDA -1,Y SIGN OF THE BCD STRING
IF A,EQ,#DMINUS SIGN NEGATIVE
LDA #$80
STA SIGN,X
*
ENDIF
*
* SET EXPONENT TO FRACTSIZE-1
*
LDD #FRACSZ-9
STD EXP,X
*
* NORMALIZE SIGNIFICAND
*
LBSR LNORM
*
*
RTS RETURN
*
*
PAG
************************************************************
*
* PROCEDURE DECBIN
*
* DECBIN CONVERTS A FLOATING PT. NO. THAT IS
* REPRESENTED BY AN UNPACKED BCD STRING INTO ITS
* INTERNAL BINARY REPRESENTATION. THE BCD STRING
* HAS THE FOLLOWING FORM:
*
* +-------------------+---+-----------------+---+
* | 19 DIGIT FRACT. |SF | 4 DIGIT EXP. |SE |
* +-------------------+---+-----------------+---+
*
* SF = SIGN FRACTION ; 0 = PLUS, -1 = MINUS
* SE = SIGN EXPONENT ; SAME
*
* LOCAL STORAGE ON THE STACK
*
BDEXP EQU 0 BINARY DECIMAL EXPONENT
TCTL EQU BDEXP+2 TEMP LOC. OF CTL. BYTE
TRND EQU TCTL+1 TEMP LOC. OF ROUNDING PREC.
*
*
DECBIN EQU *
*
* CHECK FOR A ZERO FRACTION IF SO RETURN A TRUE ZERO
*
LDY FRACT2,U
LEAY DECSIG,Y POINT AT THE DECIMAL EXPONENT
CLRA
LDB A,Y GET FIRST DIGIT
ANDB #$0F MASK OFF UPPER NIBBLE
WHILE B,EQ,#0
INCA
LDB A,Y
ANDB #$0F
IF A,GE,#SIGDIG
LDB #$FF
*
ENDIF
*
ENDWH
IF A,GE,#SIGDIG FRACTIONS ALL ZEROS
LBSR RTZERO RETURN A TRUE ZERO
*
LBRA EXITIN EXIT ROUTINE
*
ENDIF
*
LEAS -(TRND+1),S CREATE SPACE FOR LOCALS
*
* CONVERT BCD EXPONENT STRING TO A BINARY INTEGER
* RESULT TO RESIDE IN EXP2
*
LDY FRACT2,U
LEAY DECEXP,Y POINT Y AT THE BCD EXPONENT
LEAX BDEXP,S POINT TO THE LOC. OF THE BCD EXP.
LDB #EXPDIG NO. OF BCD DIGITS IN EXP
LDA #EXPLEN NO. OF BYTES IN BIN. DEC. EXP.
*
LBSR STRINT BCD STRING TO BIN. INTEGER
*
* CHECK THE SIGN OF THE EXPONENT; IF NEGATIVE
* COMPLEMENT THE RESULT OF STRINT
*
LDY FRACT2,U
LDA SE,Y
IF A,EQ,#DMINUS EXPONENT NEGATIVE
COM BDEXP,S
NEG BDEXP+1,S
IFCC CC
INC BDEXP,S
*
ENDIF
*
ENDIF
*
* CONVERT BCD FRACTION TO AN INTEGER VALUED FLOATING VALUE
*
LEAY DECSIG,Y POINT TO SIGN OF BCD FRACTION
LEAX RESULT,U POINT TO THE LOC. OF F.P. RESULT
LDB #SIGDIG NO. OF BCD DIGITS IN FRACTION
LDA #SIGLEN-1 NO. OF BYTES IN THE FRACTION
*
BSR STRBIN BCD STRING TO FLOATING INTEGER
*
* NOW MASSAGE THE FLOATING INTEGER SO THAT THE INFLUENCE
* OF THE BASE 10 EXPONENT( BDEXP ) IS TAKEN INTO ACCOUNT
* THIS IS DONE BY REPEATED MULTIPLICATIONS OR DIVISIONS
* BY 10 USING THE BASE 10 EXPONENT AS A COUNTER FOR THIS
* PROCCESS. THE BASE 10 EXPONENT MUST FIRST BE ADJUSTED
* BY A FACTOR OF P TO TAKE INTO ACCOUNT THE LOCATION OF
* DECIMAL IN THE ORIGINAL BCD FRACTION STRING. SINCE P
* IS JUST THE LOCATION OF THE PT. FROM THE LEAST SIG.
* END OF THE STRING, THEN ALL ONE DOES IS SUBTRACT P
* FROM THE BASE 10 EXPONENT.
*
* ADJUSTS EXPONENT; SUBTRACT P FROM BDEXP
*
CLR TPARAM,U
LDD TPARAM,U VALIDATE P
IFCC LT P NEGATIVE
BRA INVLD GO TO INVALID
*
ENDIF
IF D,GT,#MAXP IF P TOO BIG
*
INVLD EQU *
*
LDA #7 SIGNAL INVALID OPERATION = 7
LBSR IOPSET
LDD #MAXP DEFAULT TO P = MAX
STD TPARAM,U
*
ENDIF
LDD BDEXP,S GET DECIMAL EXPONENT
SUBD TPARAM,U SUBTRACT P
STD BDEXP,S RESTORE DECIMAL EXPONENT
*
* PERFORM THE OPERATIONS IN EXTENDED PRECISION
* WITH ROUND TO NERAEST IN EFFECT.
*
LDA [PFPCB,U] GET CONTROL BYTE
STA TCTL,S SAVE IT
ANDA #$FF-(CTLRND+CTLSIZ)
ORA #PREXT+RN
STA [PFPCB,U] RESET CONTROL BYTE
*
LDA RPREC,U GET CURRENT ROUNDING PRECISION
STA TRND,S SAVE IT
LDA #EXT REPLACE WITH EXTENDED
STA RPREC,U
*
* SAVE THE FLOATING INTEGER,I , ON THE S STACK
*
LEAS -ARGSIZ,S CREAT SPACE
LEAX RESULT,U SOURCE
LEAY 0,S DESTINATION
LBSR FPMOVE MOVE I TO TEMP
*
* CALCULATE 10^[(W-P)] AND PLACE IT IN ARG2
*
LDD BDEXP+ARGSIZ,S GET BASE TEN EXPONENT
IFCC LT BASE TEN EXPONENT NEGATIVE
COMA
COMB
ADDD #01
*
ENDIF
*
LBSR PWRTEN
*
LEAY ARG2,U DESTINATION
LBSR FPMOVE MOVE 10^[(W-P)]
*
* MOVE I BACK TO ARG1 AND DEOENDING ON THE SIGN OF THE
* BASE TEN EXPONENT EITHER MULTIPLY IT BY 10^(W-P)
* ( EXP. POSITIVE ) OR DIVIDE BY 10~(W-P) (EXP. NEGATIVE )
*
LEAX 0,S SOURCE
LEAY ARG1,U DESTINATION
LBSR FPMOVE MOVE I TO ARG1
*
LEAS ARGSIZ,S REMOVE TEMP I FROM STACK
*
* ZERO OUT THE STACK FRAME RESULT
*
LEAX RESULT,U
LDB #CLRALL CLEAR ALL OF THE ARGUMENT
LBSR CLRES
*
LDD BDEXP,S CHECK SIGN BASE TEN EXP.
IFCC GE BASE TEN EXPONENT POSITIVE
LBSR FMUL MULTIPLY I * 10^(W-P)
*
ELSE BASE TEN EXPONENT NEGATIVE
LBSR FDIV DIVIDE I / 10~(W-P)
*
ENDIF
*
*
* RESTORE ORIGINAL CONTROL BYTE
*
LDD TCTL,S ORIGINAL CTL. BYTE AND PREC.
STA [PFPCB,U] RESTORE CONTROL BYTE
STB RPREC,U RESTORE ROUNDING PRECISION
*
* CLEAR THE INEXACT BIT FROM ANY PREVIOUS OPERATIONS
* THE FINAL ROUND OR THE CHECK FOR VALID RESULT
* WILL HAVE FINAL SAY ON INEXACT.
*
LDA TPARAM,U
ANDA #$FF-ERRINX CLEAR INEXACT BIT
STA TPARAM,U
*
* SET UP THE FINAL ROUND
*
LEAX RESULT,U POINTER TO THE ARGUMENT
CLR STIKY,U CLEAR STICKY FROM PREVIOUS ROUND
CLRB NO SHIFTING IN DENORM
*
LBSR DENORM SET STIKY
*
* NOW ROUND THE RESULT TO THE DESIRED PRECISION AS
* PER CALLERS ROUNDING MODE AND PRECISION
*
LBSR ROUND
*
*
* CHECK FOR OVERFLOW AND UNDERFLOW AND TAKE APPROPRIATE
* ACTION DEPENDING WHETHER TRAPS ARE ENABLED OR NOT.
*
LBSR CHKUNF CHECK FOR UNDERFLOW
IFCC EQ
*
* IF TRAPS ENABLED THEN RETURN A "NAN" ELSE INVOKE
* UNFL_NO_TRAP
*
LDY PFPCB,U POINT AT CONTROL BLOCK
LDA ENB,Y
ANDA #ENBUNF UNDEFLOW TRAP ENABLE FLAG
IFCC NE TRAP ENABLED
LBSR RTNAN RETURN A "NAN"
*
ELSE TRAP DISABLED
LBSR UNFLNT NO TRAP HANDLER
*
ENDIF TRAPS ENABLED
*
ENDIF UNDERFLOW CHECK
*
* CKECK FOR OVERFLOW
*
LBSR CHKOVF
IFCC EQ
*
* IF TRAPS ENABLED THEN RETURN A "NAN" ELSE INVOKE
* OVFL_NO_TRAP
*
LDY PFPCB,U LOOK AT CONTROL BLOCK
LDA ENB,U
ANDA #ENBOVF OVERFLOW TRAP ENABLE FLAG
IFCC NE TRAP ENABLED
LBSR RTNAN RETURN A "NAN"
*
ELSE TRAP DISABLED
LBSR OVFLNT NO TRAP HANDLER
*
ENDIF TRAP ENABLED
*
ENDIF OVERFLOW CHECK
*
EXTINS EQU * EXIT POINT FOR INS
*
LEAS (TRND+1),S CLEAN UP LOCCALS FROM STACK
*
*
EXITIN EQU * DECBIN EXIT POINT
*
*
RTS RETURN
*
* LOCAL EQUATES
*
EXPLEN EQU 2
SIGLEN EQU 9
ACCLEN EQU SIGLEN-1
*
*
*
MUL10 MACR
****************************************************
*
* MUL10
*
* MUL10 TAKES A MULTI- PRECISION BINARY INTEGER
* AND MULTIPLIES IT BY 10. THIS OPERATION IS USEFULL
* FOR PERFORMING DECIMAL TO BINARY CONVERSIONS. UPON
* INVOCATION REG. X MUST POINT TO THE MSBYTE OF THE
* MULTI-BYTE ARGUMENT.
*
* ON ENTRY: X - POINTS TO THE MSBYTE OF THE INPUT
* OPERAND.
*
* ON EXIT: THE INPUT ARGUMENT IS MULTIPLIED BY 10
*
* X IS UNCHANGED; A & B DESTROYED
*
* TO INVOKE MUL10:
*
* MUL10 X,< BYTE LENGTH OF OPERAND >
*
* CHECK FOR PROPER NO. OF ARGUMENTS
*
IFNE NARG-2
FAIL ** TOO MANY OR TOO FEW INPUT ARGUMENTS **
EXIT
ENDC
*
* CREATE A TEMPORARY A TEMPORARY ACCUMULATOR ON THE STACK
*
LEAS -\1,S
*
* MULTIPLY INPUT BY 2 I.E. LEFT SHIFT ONCE
*
ANDCC #NC CLEAR CARRY
LSHIFT 0,X,(\1) LEFT SHIFT
*
* COPY ARG*2 TO A TEMPORARY ACCUMULATOR
*
LDB #(\1) ARGUMENT SIZE
WHILE B,GT,#0
DECB
LDA B,X SOURCE
STA B,S DESTINATION
*
ENDWH
*
* LEFT SHIFT ARGUMENT TWICE MORE TO YIELD 8*
* INPUT ARGUMENT.
*
LDB #2
WHILE B,GT,#0
ANDCC #NC CLEAR CARRY
LSHIFT 0,X,(\1) LEFT SHIFT
DECB DECREMENT COUNTER
*
ENDWH
*
* NOW ADD 8*INPUT TO 2*INPUT TO YIELD 10*INPUT
*
LDB #(\1) ARGUMENT LENGTH
DECB CONVERT LENGTH TO OFFSET
*
CLRA
WHILE B,GE,#0
RORA RESTORE CARRY
LDA B,X GET ARG1
ADCA B,S ADD IN ARG2
STA B,X SAVE RESULT
ROLA SAVE CARRY IN A
DECB DECREMENT INDEX
*
ENDWH
*
LEAS \1,S CLEAN UP STACK
*
*
ENDM
*
*
PAGE
*********************************************************
*
* PROCEDURE STRINT
*
* STRINT CONVERTS AN UNSIGNED DECIMAL VALUE( RE-
* PRESENTED BY AN ARRAY OF UNPACKED BCD DIGITS) TO
* AN UNSIGNED BINARY INTEGER .
*
* ON ENTRY: Y - POINTS TO THE START OF THE BCD ARRAY
*
* X - POINTS TO THE START OF THE ACCUMULATOR
* FOR THE BINARY RESULT.
*
* A - CONTAINS THE LENGTH OF THE BINARY RESULT
* ( IN BYTES )
*
* B - CONTAINS THE NUMBER OF BYTES IN THE BCD ARRAY
*
* ON EXIT: THE BINARY ACCUMULATOR POINTED TO BY X CONTAINS
* THE BINARY INTEGER EQUIVALENT TO THE BCD STRING.
*
* X, Y, A, B - UNCHANGED
*
* LOCAL STORAGE ON THE STACK
*
* 0,S - BYTE LENGTH OF THE BINARY RESULT
* 1,S - BYTE LENGTH OF THE BCD ARRAY
* 2,S - POINTER TO THE BINARY RESULT
* 4,S - POINTER TO THE BCD ARRAY
*
*
*
*
STRINT EQU *
*
PSHS X,Y,A,B SAVE CALLERS REGISTERS
*
* ZERO OUT THE BINARY ACCUMULATOR
*
WHILE A,GT,#0
DECA
CLR A,X
*
ENDWH
*
* SKIP OVER THE LEADING ZEROS IN THE BCD ARRAY
*
CLRA
LDB A,Y
WHILE B,EQ,#0
INCA
LDB A,Y
IF A,EQ,(1,S) BYTE INDEX = MAX INDEX
LDB #-1 TERMINATE LOOP
*
ENDIF
*
ENDWH
*
* CONVERT REMAINING BCD DIGITS TO BINARY INTEGER
*
*
*
WHILE A,LT,(1,S),L CONVERT BCD ARRAY
*
* SAVE BYTE INDEX INTO BCD ARRAY
*
PSHS A
*
*
* MULTIPLY BINARY ACCUMULATOR BY 10
*
LDB 1,S BINARY ACCUMULATOR LENGTH
IF B,EQ,#EXPLEN EXPONENT CONVERSION
MUL10 X,EXPLEN
*
ELSE SIGNIFICAND CONVERSION
MUL10 X,ACCLEN
*
ENDIF
*
* ADD IN NEXT BCD DIGIT TO BINARY ACCUMULATOR
*
LDA 0,S BCD BYTE INDEX
LDA A,Y GET NEXT BCD DIGIT
ANDA #$0F MASK OFF UPPER NIBBLE
LDB 1,S BIN. ACC. LENGTH
DECB OFFSET TO LSBYTE OF BIN ACC
ADDA B,X
STA B,X
*
* PROPAGATE CARRY TO HIGHER ORDER BYTES
*
ANDA #00 CLEAR A, SAVE CCR
ROLA SAVE CARRY
DECB
WHILE B,GE,#0 PROPAGATE CARRY
IFTST A,NE,#0
ADDA B,X ADD IN CARRY
STA B,X
ANDA #00 CLEAR A, SAVE CCR
ROLA SAVE CARRY
DECB
*
ELSE
LDB #-1 TERMINATE LOOP
*
ENDIF
*
ENDWH
*
* INCREMENT BYTE INDEX
*
PULS A
INCA
*
ENDWH CONVERT BCD ARRAY
*
*
RET PULS X,Y,A,B,PC RESTORE AND RETURN
*
*